import type { DocumentFetchConfig } from '../index'
import type {
  IframeOperationConfig,
  IframeOperationResult,
} from '../processors/iframe_operator'
import { logger } from '../../../types/constants'
import { ToolKit } from '../../utils/toolkit'
import { IframeOperator } from '../processors/iframe_operator'

/**
 * 下载触发配置
 */
export interface DownloadTriggerConfig {
  downloadButtonSelector: string
  preClickCheck?: ($button: JQuery<HTMLElement>) => boolean
  postClickAction?: ($button: JQuery<HTMLElement>) => void
  fetchConfig?: Partial<DocumentFetchConfig>
  waitAfterClick?: number
}

/**
 * 下载触发结果
 */
export interface DownloadTriggerResult {
  success: boolean
  buttonFound: boolean
  buttonText?: string
  buttonHref?: string
  error?: Error
  methodUsed?: string
  duration?: number
  statusCode?: number
}

/**
 * 下载触发器（涉及元素点击必须使用 iframe）
 */
export class DownloadTrigger {
  private readonly name: string = 'DownloadTrigger'
  private readonly iframeOperator: IframeOperator = IframeOperator.getInstance()
  private readonly WAIT_AFTER_CLICK: number = 500 // 点击后等待时间（毫秒）

  /**
   * 触发下载
   */
  public async triggerDownload(
    detailUrl: string,
    config: DownloadTriggerConfig,
  ): Promise<IframeOperationResult<DownloadTriggerResult>> {
    const { timeout, retryCount } = config.fetchConfig || {}
    const iframeConfig: IframeOperationConfig = {
      url: detailUrl,
      timeout,
      retryCount,
      iframeClass: 'download-trigger-iframe',
    }

    return this.iframeOperator.executeOperation(
      iframeConfig,
      $iframeDoc => this.executeDownload($iframeDoc, config),
      'triggerDownload',
    )
  }

  /**
   * 执行下载的具体实现
   */
  private async executeDownload(
    $iframeDoc: JQuery<Document>,
    config: DownloadTriggerConfig,
    statusCode?: number,
  ): Promise<DownloadTriggerResult> {
    const $downloadButton = $iframeDoc.find(config.downloadButtonSelector)

    if (!$downloadButton.length) {
      return {
        success: false,
        buttonFound: false,
        statusCode,
      }
    }

    // 预点击检查
    if (config.preClickCheck && !config.preClickCheck($downloadButton as JQuery<HTMLElement>))
      throw new Error('下载按钮预检查失败')

    const buttonInfo = {
      buttonText: $downloadButton.text().trim(),
      buttonHref: $downloadButton.attr('href'),
    }

    // 验证按钮状态
    if ($downloadButton.is(':disabled'))
      throw new Error('下载按钮不可用')

    // 点击下载按钮
    try {
      $downloadButton[0].click()
      await ToolKit.async.delay(config.waitAfterClick || this.WAIT_AFTER_CLICK)
    }
    catch (error) {
      throw new Error(`点击下载按钮失败: ${error instanceof Error ? error.message : String(error)}`)
    }

    // 点击后操作
    if (config.postClickAction) {
      try {
        config.postClickAction($downloadButton as JQuery<HTMLElement>)
      }
      catch (error) {
        logger.warn(`${this.name} 下载后操作执行失败:`, error)
      }
    }

    return {
      success: true,
      buttonFound: true,
      statusCode,
      ...buttonInfo,
    }
  }
}
